package de.unikoblenz.west.csxpoi;

import java.util.Calendar;

import de.unikoblenz.west.csxpoi.R;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

/**
 * DateSeekBar is a SeekBar, that does not have any thumb image and enables the
 * user to scroll on an area. By scrolling, he sets the current date and the
 * events on the maps are updated.
 * 
 * @author Daniel Schmeiss
 * 
 */
public class DateSeekBar extends SeekBar implements OnSeekBarChangeListener {

	/**
	 * animations constants in milliseconds
	 */
	private final static int DURATION = 3000, ANIMATION_TIME = 300;

	/**
	 * start progress of the seekbar
	 */
	private int start;

	/**
	 * flag if it is the first touch of the seekbar
	 */
	private boolean first = true;

	/**
	 * a static variable of this {@link DateSeekBar}
	 */
	private static DateSeekBar mDateSeekBar;

	/**
	 * {@link Handler} for the timer
	 */
	private static Handler mHandler = new Handler();

	/**
	 * fade in- and out animations
	 */
	private static Animation mFadeIn, mFadeOut;

	/**
	 * Constructor, that initializes this {@link DateSeekBar}
	 * 
	 * @param context
	 *            {@link Context}
	 * @param attrs
	 *            {@link AttributeSet}
	 * @param defStyle
	 *            int
	 */
	public DateSeekBar(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	/**
	 * Constructor, that initializes this {@link DateSeekBar}
	 * 
	 * @param context
	 *            {@link Context}
	 * @param attrs
	 *            {@link AttributeSet}
	 */
	public DateSeekBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	/**
	 * Constructor, that initializes this {@link DateSeekBar}
	 * 
	 * @param context
	 *            {@link Context}
	 */
	public DateSeekBar(Context context) {
		super(context);
		init();
	}

	/**
	 * initialize this SeekBar and set the graphics, maximum value, listener and
	 * animations
	 */
	private void init() {
		mDateSeekBar = this;
		// remove thumb image and set the background image
		Drawable d = getResources().getDrawable(R.drawable.date_chooser);
		this.setProgressDrawable(d);
		this.setThumb(null);
		this.setHapticFeedbackEnabled(true);

		this.setMax(Constants.SEEKBAR_RESOLUTION);
		this.setOnSeekBarChangeListener(this);

		// initialize animations
		mFadeIn = new AlphaAnimation(0, 1);
		mFadeIn.setDuration(ANIMATION_TIME);
		mFadeOut = new AlphaAnimation(1, 0);
		mFadeOut.setDuration(ANIMATION_TIME);
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		// only react to user input
		if (fromUser) {
			// if it is the first change of progress, remember the start point
			if (first) {
				first = false;
			}
			// after the first change, adjust the calendar and update the view
			else {
				CsxPoiActivity.mCal.add(Calendar.DAY_OF_YEAR, progress - start);
				CsxPoiActivity.updateMapOverlay();
				CsxPoiActivity.updateDateText();
			}
			start = progress;
		}
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
		first = true;
		// remove timer
		mHandler.removeCallbacks(hideSeekBar);
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		// reset the seekbar status
		seekBar.setProgress(Constants.SEEKBAR_RESOLUTION / 2);
		// start timer
		mHandler.postDelayed(hideSeekBar, DURATION);
	}

	/**
	 * setActive sets this {@link DateSeekBar} visible and starts a fade in
	 * animation. It also starts the timer, so that this widget will also fade
	 * out after an idle time.
	 */
	public static void setActive() {
		if (mDateSeekBar.getVisibility() != View.VISIBLE)
			mDateSeekBar.startAnimation(mFadeIn);
		mDateSeekBar.setVisibility(View.VISIBLE);
		// start timer
		mHandler.removeCallbacks(hideSeekBar);
		mHandler.postDelayed(hideSeekBar, DURATION);
	}

	/**
	 * If this {@link Runnable} is started, the {@link DateSeekBar} will fade
	 * out and be invisible.
	 */
	private static Runnable hideSeekBar = new Runnable() {
		public void run() {
			mDateSeekBar.startAnimation(mFadeOut);
			mDateSeekBar.setVisibility(View.GONE);
			mHandler.removeCallbacks(hideSeekBar);
		}
	};
}
